package com.audi.box.controller;

import java.util.ArrayList;

import android.content.Context;

import com.audi.box.adapter.SQLiteAsusHelperHistory;
import com.audi.box.server.message.ActionMessage;
import com.audi.box.service.HistoryService;
import com.audi.box.service.HistoryServiceImp;
import com.audi.dto.DeviceItem;
import com.audi.dto.HistoryItem;
import com.audi.dto.PlaceItem;
import com.audi.dto.SceneItem;
import com.audi.utils.Constants;

/**
 * @author CuongPH7
 */
public class HistoryController implements IController {
    
    // Usage for check loop action, only log history a action three times
    private static String[] previous = {"", ""};
    
    private static Object hclObj = new Object();
    private HistoryService historyService;
    private static HistoryController historyController = null;
    
    /**
     * Class constructor specifying Context to create
     * 
     * @param context
     *            android.content.Context
     * @throws Exception
     *             if (can not create HistoryServiceImp
     */
    public HistoryController(final Context context) throws Exception {
        
        historyService = new HistoryServiceImp(
                new SQLiteAsusHelperHistory(context));
    }
    
    /**
     * Class constructor specifying HistoryService to create.
     * 
     * @param historyService
     *            HistoryService
     * @see HistoryService
     */
    public HistoryController(HistoryService historyService) {
        this.historyService = historyService;
    }
    
    public static HistoryController getInstance(final Context context)
            throws Exception {
        if (historyController == null) {
            synchronized (hclObj) {
                if (historyController == null) {
                    historyController = new HistoryController(context);
                }
            }
        }
        
        return historyController;
    }
    
    /**
     * Inject HistoryService.
     * 
     * @param historyService
     *            HistoryService
     * @see HistoryService
     */
    public void setHistoryService(HistoryService historyService) {
        this.historyService = historyService;
    }
    
    private int addHistory(String actionName, String historyType, int target,
            String name, String icon,
            String source, String destination,
            String description, int userId, String userName) {
        HistoryItem history = new HistoryItem();
        
        history.setTarrgetAction(actionName);
        history.setTarrgetType("place");
        history.setTarrgetId(target);
        history.setTarrgetName(name);
        history.setTarrgetIcon(icon);
        history.setTarrgetSource(source);
        history.setTarrgetDestination(destination);
        history.setDescription(description);
        history.setUserId(userId);
        history.setUserName(userName);
        
        return historyService.addHistory(history);
    }
    
    private int addHistory(String actionName, String historyType, int targetId,
            String source, String destination,
            String description, int userId, String userName) {
        HistoryItem history = new HistoryItem();
        
        history.setTarrgetAction(actionName);
        history.setTarrgetType("place");
        history.setTarrgetId(targetId);
        history.setTarrgetSource(source);
        history.setTarrgetDestination(destination);
        history.setDescription(description);
        history.setUserId(userId);
        history.setUserName(userName);
        
        return historyService.addHistory(history);
    }
    
    protected int addHistoryDevice(int action,
            DeviceItem oldDevice, DeviceItem newDevice,
            int userId, String userName) {
        
        return addHistoryDevice(action, oldDevice, newDevice, userId, userName, 0);
    }
    
    protected int addHistoryDevice(int action,
            DeviceItem oldDevice, DeviceItem newDevice,
            int userId, String userName,
            int count) {
        
        int target = 0;
        String actionName = null;
        String name = null, icon = null;
        String source = null, destination = null;
        String description = null;
        
        target = oldDevice.getDeviceId();
        icon = newDevice.getDeviceIcon();
        
        switch (action) {
            case ActionMessage.ADD_DEVICE:
                actionName = "Add";
                name = "A new " + Constants.DEVICE_TYPE.values()[newDevice.getDeviceType()];
                // newDevice.getDeviceType();
                description = userName
                        + " adds " + newDevice.getDeviceName()
                        + " to " + newDevice.getDevicePlace();
                break;
            
            case ActionMessage.RENAME_DEVICE:
                
                break;
            
            case ActionMessage.UPDATE_DEVICE:
                
                break;
            
            case ActionMessage.DELETE_DEVICE:
                actionName = "Delete";
                name = "Remove a " + Constants.DEVICE_TYPE.values()[newDevice.getDeviceType()];
                description = userName
                        + " removes " + newDevice.getDeviceName()
                        + " from " + newDevice.getDevicePlace();
                break;
            
            case ActionMessage.CHANGE_PLACE_OF_DEVICE:
                actionName = "Change Place";
                name = "A device is moved";
                description = newDevice.getDeviceName()
                        + " is moved to " + newDevice.getDevicePlace()
                        + " by " + userName;
                break;
            
            case ActionMessage.CHANGE_PLACE_OF_DEVICE_LIST:
                actionName = "Change Place Multi Device";
                name = count + "A device is moved";
                description = count + " devices"
                        + " are moved to " + newDevice.getDevicePlace()
                        + " by " + userName;
                break;
            
            case ActionMessage.UPDATE_FAVORITE_DEVICE:
                break;
        }
        
        return addHistory(actionName, "Device", target, name, icon, source,
                destination, description, userId, userName);
    }
    
    protected int addHistoryPlace(int action,
            PlaceItem oldPlace, PlaceItem newPlace,
            int userId, String userName) {
        
        int target = 0;
        String actionName = null;
        String name = null, icon = null;
        String source = null, destination = null;
        String description = null;
        
        target = oldPlace.getPlaceId();
        icon = newPlace.getPlaceImage();
        
        switch (action) {
            case ActionMessage.ADD_PLACE:
                actionName = "Add";
                name = "A new place";
                description = userName
                        + " adds a new place " + newPlace.getPlaceName()
                        + " at home";
                break;
            
            case ActionMessage.RENAME_PLACE:
                actionName = "Rename";
                name = "A place is renamed";
                description = userName
                        + " renames " + oldPlace.getPlaceName()
                        + " to " + newPlace.getPlaceName();
                break;
            
            case ActionMessage.UPDATE_PLACE:
                
                break;
            
            case ActionMessage.DELETE_PLACE:
                actionName = "Delete";
                name = "Remove a place";
                description = userName
                        + " removes a place " + newPlace.getPlaceName()
                        + " at home";
                
                break;
            
            case ActionMessage.CHANGE_CAPABILITY:
                actionName = "Change Capability";
                String capability = (newPlace.getCapabilityType() == Constants.PLACE_CAPABILITY.PUBLIC
                        .ordinal()) ?
                        "public"
                        : "private";
                name = newPlace.getPlaceName()
                        + " is " + capability;
                description = userName
                        + " changes capability of " + newPlace.getPlaceName()
                        + " to " + capability;
                break;
        
        }
        
        return addHistory(actionName, "Place", target, name, icon, source, destination,
                description, userId, userName);
    }
    
    protected int addHistoryScene(int action,
            SceneItem oldScene, SceneItem newScene,
            int userId, String userName) {
        
        int target = 0;
        String actionName = null;
        String name = null, icon = null;
        String source = null, destination = null;
        String description = null;
        
        target = oldScene.getSceneId();
        icon = newScene.getSceneIcon();
        
        switch (action) {
            case ActionMessage.ADD_SCENE:
                destination = newScene.getSceneTitle();
                description = "Add new Scene ";
                break;
            
            case ActionMessage.UPDATE_SCENE:
                source = oldScene.getSceneTitle();
                description = "Update " + source + " information";
                break;
            
            case ActionMessage.DELETE_SCENE:
                source = oldScene.getSceneTitle();
                description = "Delete scene";
                break;
        
        // MISSING CHANGE SCENE STATUS ???
        // MISSING CHANGE SCENE'S PLACE ???
        }
        
        return addHistory(actionName, "Scene", target, name, icon, source, destination,
                description, userId, userName);
    }
    
    public ArrayList<HistoryItem> getHistoryList() {
        return historyService.getHistoryList();
    }
}
